package com.xuecheng.content.service.jobhandler;

import com.xuecheng.base.exception.XuechengPlusException;
import com.xuecheng.content.feignclient.CourseIndex;
import com.xuecheng.content.feignclient.SearchServiceClient;
import com.xuecheng.content.mapper.CourseBaseMapper;
import com.xuecheng.content.mapper.CoursePublishMapper;
import com.xuecheng.content.model.po.CourseBase;
import com.xuecheng.content.model.po.CoursePublish;
import com.xuecheng.content.service.CoursePublishService;
import com.xuecheng.messagesdk.model.po.MqMessage;
import com.xuecheng.messagesdk.service.MessageProcessAbstract;
import com.xuecheng.messagesdk.service.MqMessageService;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;

/**
 * 课程发布的任务类
 */
@Component
@Slf4j
public class CoursePublishTask extends MessageProcessAbstract {
    @Autowired
    private CoursePublishService coursePublishService;
    @Autowired
    private SearchServiceClient searchServiceClient;
    @Autowired
    private CoursePublishMapper coursePublishMapper;
    @Autowired
    private CourseBaseMapper courseBaseMapper;

    //任务调度入口
    @XxlJob("CoursePublishJobHandler")
    public void coursePublishJobHandler() throws Exception {
        // 分片参数
        int shardIndex = XxlJobHelper.getShardIndex();
        int shardTotal = XxlJobHelper.getShardTotal();
        log.debug("shardIndex="+shardIndex+",shardTotal="+shardTotal);
        //参数:分片序号、分片总数、消息类型、一次最多取到的任务数量、一次任务调度执行的超时时间
        process(shardIndex,shardTotal,"course_publish",30,60);
    }

    //任务执行的具体逻辑
    @Override
    public boolean execute(MqMessage mqMessage) {
        //从mqMessage拿课程id
        Long courseId = Long.parseLong(mqMessage.getBusinessKey1());
        //向minio中写静态资源
        generateCourseHtml(mqMessage,courseId);
        //向elasticsearch写索引数据
        saveCourseIndex(mqMessage,courseId);
        //向redis中写缓存
        saveCourseCache(mqMessage,courseId);
        //修改课程基本表的发布状态为已发布
        CourseBase courseBase = new CourseBase();
        courseBase.setId(courseId);
        courseBase.setStatus("203002");
        courseBaseMapper.updateById(courseBase);
        return true;
    }
    //阶段一：生成课程静态化页面并上传至文件系统
    private void generateCourseHtml(MqMessage mqMessage,long courseId){
        MqMessageService mqMessageService = this.getMqMessageService();
        Long taskId = mqMessage.getId();
        //做任务幂等性处理：
        //查询数据的阶段一状态
        int stageOne = mqMessageService.getStageOne(taskId);
        if(stageOne>0){
            log.info("课程静态化已处理，无需处理");
            return;
        }
        //开始进行课程静态化处理....

        //生成html页面
        File file = coursePublishService.generateCourseHtml(courseId);
        if(file==null){
            XuechengPlusException.cast("生成的静态页面为空");
        }
        //将html上传到minio
        coursePublishService.uploadCourseHtml(courseId,file);

        //任务处理完成，写阶段一状态为完成
        mqMessageService.completedStageOne(taskId);
    }

    //阶段二：保存课程索引信息
    public void saveCourseIndex(MqMessage mqMessage,long courseId){
        MqMessageService mqMessageService = this.getMqMessageService();
        //任务Id
        Long taskId = mqMessage.getId();
        //任务幂等性处理
        Long stageState2 = Long.parseLong(mqMessage.getStageState2());
        if(stageState2>0){
            log.info("保存课程索引信息已完成，无需处理");
            return;
        }
        //开始保存课程索引信息
        CoursePublish coursePublish = coursePublishMapper.selectById(courseId);
        CourseIndex courseIndex = new CourseIndex();
        BeanUtils.copyProperties(coursePublish,courseIndex);
        Boolean add = searchServiceClient.add(courseIndex);
        if(!add){
            XuechengPlusException.cast("添加索引失败");
        }

        //任务处理完成，写阶段二状态为完成
        mqMessageService.completedStageTwo(taskId);
    }

    //阶段三：将课程信息缓存至redis
    private void saveCourseCache(MqMessage mqMessage,long courseId){

    }
}
